/*******************************************************************************
 * @file    bsp_clock.c
 * @brief   the device clock initialization
 *
 * @version 0.0.1
 *******************************************************************************
 * @license Refer License or other description Docs
 * @author  Felix
 ******************************************************************************/
#include "cpu/bsp_clock.h"
#include "flash.h"
#include "sysctrl.h"

void BSP_ClockInit(bool exth, bool extl)
{
    if(exth){
#if USE_CLOCK_EXTH
        stc_sysctrl_clk_cfg_t stcCfg;
        /* HCLK  = SYSCLK/1  */
        stcCfg.enHClkDiv   = SysctrlHclkDiv1;
        /*  PCLK = HCLK/1    */
        stcCfg.enPClkDiv   = SysctrlPclkDiv1;
        /* select XTH 32MHz */
        stcCfg.enClkSrc  = SysctrlClkXTH;
        Flash_WaitCycle(FlashWaitCycle1);
        Sysctrl_SetXTHFreq(SysctrlXthFreq20_32MHz);
        Sysctrl_ClkInit(&stcCfg);
#endif
    }

    Sysctrl_ClkSourceEnable(SysctrlClkRCL, TRUE);
    Sysctrl_SetRCLTrim(SysctrlRclFreq38400);

    /* enable XTL */
    if(extl){
        Sysctrl_XTLDriverCfg(SysctrlXtlAmp2, SysctrlXtalDriver3);
        /* Sysctrl_SetXTLStableTime(SysctrlXtlStableCycle16384); */
        M0P_SYSCTRL->PERI_CLKEN0_f.GPIO = 1;
        M0P_GPIO->PCADS_f.PC14 = 1;
        M0P_GPIO->PCADS_f.PC15 = 1;
        /* SysctrlUnlock */
        M0P_SYSCTRL->SYSCTRL2 = 0x5A5A;
        M0P_SYSCTRL->SYSCTRL2 = 0xA5A5;
        M0P_SYSCTRL->SYSCTRL0_f.XTL_EN = 1;
    }
}

void BSP_ClockDeInit(void)
{
    /**
     * @todo:
     */
}

uint32_t BSP_ClockCheck(const uint32_t waitms)
{
    uint32_t loop = 0;
    uint8_t status = 1;

    /* wait for 4096 times CPU cycles */
    while(1 != M0P_SYSCTRL->XTL_CR_f.STABLE){
        if(++loop > waitms){
            status = 0;
            break;
        }
        BSP_ClockdelayUs(1000);
    }

    if(0 == status){
        /* SysctrlUnlock */
        M0P_SYSCTRL->SYSCTRL2 = 0x5A5A;
        M0P_SYSCTRL->SYSCTRL2 = 0xA5A5;
        M0P_GPIO->PCADS_f.PC14 = 0;
        M0P_GPIO->PCADS_f.PC15 = 0;
        M0P_SYSCTRL->SYSCTRL0_f.XTL_EN = 0;
    }

    return loop;
}

/* use 24MHz frequency, the follow code execute 5.12us if count = 5 */
void BSP_ClockdelayUs(int count)
{
    count *= 3;
    for(int i = 0; i < count; i++){
         __NOP();
         __NOP();
         __NOP();
         __NOP();
    }
}
